import { BadRequestException, Inject, Injectable } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { JwtService } from '@nestjs/jwt';
import { InjectRepository } from '@nestjs/typeorm';
import { ConfigEnum } from 'src/enum/config.enum';
import { HttpEnum } from 'src/enum/http.enum';
import { SigninUserDto } from 'src/pojo/dto/signinuser.dto';
import { User } from 'src/pojo/entity/user.entity';
import { SigninUserVo } from 'src/pojo/vo/signinuser.vo';
import { SecretTool } from 'src/utils/SecretTool';
import { RedisClient } from 'src/utils/module/redis.module';
import { Repository } from 'typeorm';

@Injectable()
export class AuthService {
  @Inject()
  private redisClient: RedisClient;

  @Inject()
  private jwtService: JwtService;

  @Inject()
  private secretTool: SecretTool;

  @Inject()
  private configService: ConfigService;

  @InjectRepository(User)
  private userMapper: Repository<User>;

  // 登录
  async signIn(
    signinUserDto: SigninUserDto,
    key: string,
  ): Promise<SigninUserVo> {
    if (
      signinUserDto.type === 'sms' &&
      (!signinUserDto.phone || !signinUserDto.code)
    ) {
      throw new BadRequestException(HttpEnum.MISSING_NECESSARY_FIELD);
    }
    if (
      signinUserDto.type === 'password' &&
      (!signinUserDto.username ||
        !signinUserDto.password ||
        !signinUserDto.code)
    ) {
      throw new BadRequestException(HttpEnum.MISSING_NECESSARY_FIELD);
    }
    let user: User = null;
    if (signinUserDto.type === 'sms') {
      if (
        !(await this.redisClient.exists(`login:sms:${signinUserDto.phone}`))
      ) {
        throw new BadRequestException(HttpEnum.NEED_SMS_CAPTCHA);
      }
      const smsCode = await this.redisClient.get(
        `login:sms:${signinUserDto.phone}`,
      );
      if (smsCode !== signinUserDto.code) {
        throw new BadRequestException(HttpEnum.SMS_CAPTCHA_INCORRECT);
      }
      // 手机验证码
      user = await this.userMapper.findOneBy({ phone: signinUserDto.phone });
    } else {
      if (!(await this.redisClient.exists(`login:captcha:${key}`))) {
        throw new BadRequestException(HttpEnum.NEED_CAPTCHA);
      }
      const captcha = await this.redisClient.get(`login:captcha:${key}`);
      if (captcha.toLowerCase() !== signinUserDto.code.toLowerCase()) {
        throw new BadRequestException(HttpEnum.CAPTCHA_INCORRECT);
      }
      // 账号密码
      user = await this.userMapper.findOneBy({
        username: signinUserDto.username,
      });
    }
    if (!user) {
      throw new BadRequestException(HttpEnum.INVALID_ACCOUNT);
    }
    // 验证密码
    if (
      signinUserDto.type === 'password' &&
      this.secretTool.getSecret(signinUserDto.password + user.salt) !==
        user.password
    ) {
      throw new BadRequestException(HttpEnum.INCORRECT_USERNAME_OR_PASSWORD);
    }
    // 是否被冻结
    if (+user.status === 0) {
      throw new BadRequestException(HttpEnum.ACCOUNT_FROZEN);
    }

    const accessToken = await this.jwtService.signAsync(
      {
        userId: user.id,
        username: user.username,
      },
      {
        expiresIn: this.configService.get<string>(ConfigEnum['JWT.EXPIRESIN']),
      },
    );

    const refreshToken = await this.jwtService.signAsync(
      {
        userId: user.id,
      },
      {
        expiresIn: this.configService.get<string>(
          ConfigEnum['JWT.EXPIRESIN.REFESH'],
        ),
      },
    );
    return {
      accessToken,
      refreshToken,
    };
  }
}
